﻿using AutoMapper;
using HamcoWcs.Contract.ContractCommon;
using HamcoWcs.Contract.ContractMainTask;
using HamcoWcs.Contract.ContractMes;
using HamcoWcs.DAL;
using HamcoWcs.Entitys.SubTasks;
using HamcoWcs.Entitys.WcsLocations;
using HamcoWcs.Models.Common.Enums;
using HamcoWcs.Models.Devices;
using HamcoWcs.Models.Exceptions;
using System;
using System.Linq;

namespace HamcoWcs.Service.Srm.SrmTaskParsers
{
    /// <summary>二重入库</summary>
    public class SrmParser_DoubleInbound : SrmParserBase
    {
        public override EnumSrmRequest RequestType => EnumSrmRequest.DoubleInbound;

        public override void Deal(SrmDto srm, SrmPlc srmPlc)
        {
            // 获取此堆垛机当前的任务
            var task = GetSrmTask(srm);
            if (task == null)
            {
                _logger.AddWcsRunLog(srm.UnitId, $"处理二重入库失败，未找到{srm.MachineName}-{srm.PortName}的任务");
                return;
            }


            if (task.IsNeedSection)
            {
                //var tempLoc = _locationService.GetLocationByWcsName(task.HandOffShelf);
                _locationService.ShelfBlock(task.HandOffShelf, "WCS", $"[{task.MainTask.TaskId}]{srm.DeviceName}中转时二重入库");

                var handshelf = _locationService.GetMiddleLocation(srm.MachineName);

                if (handshelf is null)
                {
                    handshelf = _locationService.GetEmptyLocationByZone($"{srm.MachineName}Z3");
                    //handshelf.LocStatus = (int)EnumLocStatus.TempHandOff;
                    //handshelf.Remark = "";
                }

                if (handshelf is null)
                {
                    _logger.AddWcsRunLog(task.UnitId, "没有找到空的中转储位，等待中");
                    throw new SrmNotFoundEmptyException();
                };

                task.HandOffShelf = handshelf.WcsLocName;
                handshelf.LocStatus = (int)EnumLocStatus.In;
                handshelf.Remark = $"{srm.DeviceName},{task.UnitId},中转时二重入库,重新分配中转储位";
                _wcsDbContext.SaveChanges();
            }
            else
            {
                if (task.ToLoc.IsShelf())
                {
                    // 目的地是储位的处理
                    var oldloc = _wcsDbContext.WcsLocations.FirstOrDefault(x => x.WcsLocName == task.ToLoc);
                    _locationService.ShelfBlock(oldloc.WcsLocName, "WCS", "二重入库");
                }


                try
                {
                    var loc = GetEmptyLocation(task, srm);
                    task.ToLoc = loc.WcsLocName;

                    task.MainTask.OldDesMachine = task.MainTask.DesMachine;
                    task.MainTask.OldDesPosition = task.MainTask.OldDesPosition;
                    task.MainTask.OldDesType = task.MainTask.DesType;
                    task.MainTask.OldDesZone = task.MainTask.OldDesZone;
                    task.MainTask.CurrentMachine = loc.ZoneName.Substring(0, 8);
                    task.MainTask.CurrentPosition = loc.WcsLocName;
                    task.MainTask.CurrentType = "SHELF";
                    task.MainTask.CurrentZone = loc.ZoneName;
                    task.MainTask.DesMachine = loc.ZoneName.Substring(0, 8);
                    task.MainTask.DesPosition = loc.WcsLocName;
                    task.MainTask.DesType = "SHELF";
                    task.MainTask.DesZone = loc.ZoneName;
                    task.MainTask.ReasonCode = "1001";//二重入库更换储位
                    loc.LocStatus = (int)EnumLocStatus.In;
                    _wcsDbContext.SaveChanges();

                }
                catch (Exception ex)
                {
                    //task.TaskStatus = EnumSubTaskStatus.Error.ToString();
                    //task.MainTask.TaskStatus = EnumMainTaskStatus.Error.ToString();
                    _logger.AddWcsRunLog(srm.UnitId, $"处理二重入库失败，{ex.Message}");
                }
            }




        }



        private readonly IBaseMainTaskService _mainTaskService;
        private readonly IMapper _mapper;
        public SrmParser_DoubleInbound(IMapper mapper, IBaseMainTaskService mainTaskService, ILocationService locationService, WcsDbContext wcsDbContext,
            IMesCommunicateService mesCommunicateService, ILoggerService logger)
            : base(wcsDbContext, locationService, mesCommunicateService, logger)
        {
            _mainTaskService = mainTaskService;
            _mapper = mapper;
        }

        private WcsLocation GetEmptyLocation(SubTask subTask, SrmDto srm)
        {
            var srcLoc = _wcsDbContext.WcsLocations
                .Where(x => x.WcsLocName == subTask.ToLoc)
                .FirstOrDefault();

            if (srcLoc is null) throw new Exception("获取原储位失败");

            srcLoc.IsLock = true;
            srcLoc.Remark = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}][{subTask.MainTask.TaskId}]{srm.MachineName}-{srm.PortName}发送二重入库，old:{srcLoc.UnitId}";

            string zoneName = srcLoc.ZoneName;

            var loc = _wcsDbContext.WcsLocations
                .Where(x => x.LocType == "shelf")
                .Where(x => x.ZoneName == zoneName)
                .Where(x => x.LocStatus == (int)EnumLocStatus.Empty && string.IsNullOrEmpty(x.UnitId))
                .Where(x => !x.IsLock && !x.SrmOccupyFlag)
                .OrderBy(d => d.Lev)
                .FirstOrDefault();

            if (loc is null)
            {
                loc = _wcsDbContext.WcsLocations
                                 .AsQueryable()
                                 .Where(x => x.LocType == "shelf")
                                 .Where(d => d.LocStatus == (int)EnumLocStatus.Empty)
                                 .Where(d => !d.IsLock && !d.SrmOccupyFlag)
                                 .OrderBy(d => d.Lev)
                                 .FirstOrDefault();
            }

            return loc;
        }


    }
}
